#import "sprite_game_enemy_boss3.h"

#define ENEMY_STATE_BOSS3_APPEAR 13
#define ENEMY_STATE_BOSS3_SPECIAL_ATTACK 14
#define ENEMY_STATE_BOSS3_STAGE_CHANGE 15

#define BOSS_3_STAGE_1 0
#define BOSS_3_STAGE_2 1
#define BOSS_3_STAGE_3 2

@implementation SpriteGameEnemyBoss3

- (id)initSpriteGameEnemyBoss3
{
	if ((self = [super initSpriteGameEnemy]))
	{
		objectName_ = "object sprite game enemy type boss 3";
		
		/*box2d
		*/
		fixtureBoss3Head_ = NULL;
		fixtureBoss3Body_ = NULL;
		fixtureBoss3Ass_ = NULL;
	}
	return self;
}

- (void)draw
{
	CGPoint point;
	
	if (ENEMY_STATE_BOSS3_APPEAR == state_)
	{
		point = ccpSub(boss3BornPoint_, self.positionInPixels);
		glColor4f(1, 1, 1, 1);
		glLineWidth(3.0);
		uiRenderLine(CGPointZero, point);
	}
}

- (void)tickBoss3CreateLeftSlave:(ccTime)Time
{
	SMissionEnemy _Data;

	[self unschedule:@selector(tickBoss3CreateLeftSlave:)];

	if (state_ == ENEMY_STATE_BOSS3_SPECIAL_ATTACK)
	{
		return;
	}

	_Data.enemy_type = ENEMY_TYPE_5;
	_Data.ai_type = ENEMY_AI_TYPE_3;
	_Data.born_area.path_type = MISSION_ENEMY_PATH_ELEMENT_AREA_INDEX;
	_Data.move_speed = 200;
	_Data.move_speed_variance = 0;
	_Data.stand_time = 0;
	_Data.drop_heart_point = 0;
	/*left
	*/
	_Data.born_area.area_index = 9;
	boss3SlaveLeftHandle_ = [[sprite_game_enemy alloc] initSpriteGameEnemy:&_Data];
	[g_LayerGameObject AddEnemy:boss3SlaveLeftHandle_];
	boss3SlaveLeftHandle_.boss3Handle = self;
	[boss3SlaveLeftHandle_ AiCreate];
}

- (void)tickBoss3CreateRightSlave:(ccTime)Time
{
	SMissionEnemy _Data;

	[self unschedule:@selector(tickBoss3CreateRightSlave:)];

	if (state_ == ENEMY_STATE_BOSS3_SPECIAL_ATTACK)
	{
		return;
	}

	_Data.enemy_type = ENEMY_TYPE_5;
	_Data.ai_type = ENEMY_AI_TYPE_3;
	_Data.born_area.path_type = MISSION_ENEMY_PATH_ELEMENT_AREA_INDEX;
	_Data.move_speed = 200;
	_Data.move_speed_variance = 0;
	_Data.stand_time = 0;
	_Data.drop_heart_point = 0;
	/*right
	*/
	_Data.born_area.area_index = 19;
	boss3SlaveRightHandle_ = [[sprite_game_enemy alloc] initSpriteGameEnemy:&_Data];
	boss3SlaveRightHandle_.boss3Handle = self;
	[g_LayerGameObject AddEnemy:boss3SlaveRightHandle_];
	boss3SlaveRightHandle_.boss3Handle = self;
	[boss3SlaveRightHandle_ AiCreate];
}

- (void)tickBoss3SpecialAttack:(ccTime)Time
{
	[self ActionBoss3SpecialAttack];
}

- (void)createBody
{
	int i;
	int _VertexCount;
	float _Ratio;
	b2Vec2 *_Vertex;
	b2PolygonShape _PolygonShape;
	b2FixtureDef _FixtureDef;

	[super createBody];

	_Ratio = 1 / CMgrGamePhysics::Ratio();
	_FixtureDef.density = 1.0f;
	_FixtureDef.isSensor = true;

	/*head
	*/
	_VertexCount = g_CfgGameBoss3Data.box2d_collision_point_table_head.size();
	_Vertex = ptCreateCollisionVertex(&g_CfgGameBoss3Data.box2d_collision_point_table_head);
	for (i = 0; i < _VertexCount; ++i)
	{
		_Vertex[i] = ptScaleVector_same(_Vertex[i], _Ratio);
	}
	_PolygonShape.Set(_Vertex, _VertexCount);
	free(_Vertex);
	_FixtureDef.shape = &_PolygonShape;
	fixtureBoss3Head_ = box2dBody_->CreateFixture(&_FixtureDef);
	/*body
	*/
	_VertexCount = g_CfgGameBoss3Data.box2d_collision_point_table_body.size();
	_Vertex = ptCreateCollisionVertex(&g_CfgGameBoss3Data.box2d_collision_point_table_body);
	for (i = 0; i < _VertexCount; ++i)
	{
		_Vertex[i] = ptScaleVector_same(_Vertex[i], _Ratio);
	}
	_PolygonShape.Set(_Vertex, _VertexCount);
	free(_Vertex);
	_FixtureDef.shape = &_PolygonShape;
	fixtureBoss3Body_ = box2dBody_->CreateFixture(&_FixtureDef);
	/*ass
	*/
	_VertexCount = g_CfgGameBoss3Data.box2d_collision_point_table_ass.size();
	_Vertex = ptCreateCollisionVertex(&g_CfgGameBoss3Data.box2d_collision_point_table_ass);
	for (i = 0; i < _VertexCount; ++i)
	{
		_Vertex[i] = ptScaleVector_same(_Vertex[i], _Ratio);
	}
	_PolygonShape.Set(_Vertex, _VertexCount);
	free(_Vertex);
	_FixtureDef.shape = &_PolygonShape;
	fixtureBoss3Ass_ = box2dBody_->CreateFixture(&_FixtureDef);
}

- (void)destroyBody
{
	[super destroyBody]
	fixtureBoss3Head_ = NULL;
	fixtureBoss3Body_ = NULL;
	fixtureBoss3Ass_ = NULL;
}

- (void)Boss3CreateSlave
{
	SMissionEnemy _Data;

	_Data.enemy_type = ENEMY_TYPE_5;
	_Data.ai_type = ENEMY_AI_TYPE_3;
	_Data.born_area.path_type = MISSION_ENEMY_PATH_ELEMENT_AREA_INDEX;
	_Data.move_speed = 200;
	_Data.move_speed_variance = 0;
	_Data.stand_time = 0;
	_Data.drop_heart_point = 0;
	/*left
	*/
	_Data.born_area.area_index = 9;
	boss3SlaveLeftHandle_ = [[sprite_game_enemy alloc] initSpriteGameEnemy:&_Data];
	[g_LayerGameObject AddEnemy:boss3SlaveLeftHandle_];
	boss3SlaveLeftHandle_.boss3Handle = self;
	[boss3SlaveLeftHandle_ AiCreate];
	/*right
	*/
	_Data.born_area.area_index = 19;
	boss3SlaveRightHandle_ = [[sprite_game_enemy alloc] initSpriteGameEnemy:&_Data];
	boss3SlaveRightHandle_.boss3Handle = self;
	[g_LayerGameObject AddEnemy:boss3SlaveRightHandle_];
	boss3SlaveRightHandle_.boss3Handle = self;
	[boss3SlaveRightHandle_ AiCreate];
}

- (void)ActionBoss3Appear
{
	CCSequence *_Seq;
	id _ActionMove;
	CCCallFuncN *_CallBackAppearMoveOver;

	if (state_ == ENEMY_STATE_DIE)
	{
		return;
	}

	state_ = ENEMY_STATE_BOSS3_APPEAR;
	_ActionMove = tcCreateActionMove(self.positionInPixels, g_CfgGameScrrenArea[4].center, [self GetMoveSpeed]);
	_CallBackAppearMoveOver = [CCCallFuncN actionWithTarget:self selector:@selector(CallBackBoss3ActionAppearMoveOver:)];
	_Seq = [CCSequence actions:_ActionMove, _CallBackAppearMoveOver, nil];
	[self runAction:_Seq];
}

- (void)ActionBoss3SpecialAttack
{
	CCSequence *_Seq;
	id _ActionMove;
	CCCallFuncN *_CallBackMoveOver;

	if (state_ == ENEMY_STATE_DIE)
	{
		return;
	}

	/*stop special attack tick
	*/
	[self unschedule:@selector(tickBoss3SpecialAttack:)];

	state_ = ENEMY_STATE_BOSS3_SPECIAL_ATTACK;
	[self unschedule:@selector(tickBoss3CreateLeftSlave:)];
	[self unschedule:@selector(tickBoss3CreateRightSlave:)];
	[self StopAction];
	[self PlayAni:ENEMY_ANI_MOVE];
	_ActionMove = tcCreateActionMove(self.positionInPixels, g_CfgGameScrrenArea[4].center, moveSpeed_);
	_CallBackMoveOver = [CCCallFuncN actionWithTarget:self selector:@selector(CallBackBoss3ActionSpecialAttackMoveOver:)];
	_Seq = [CCSequence actions:_ActionMove, _CallBackMoveOver, nil];
	[self runAction:_Seq];

	/*clear left and right
	*/
	if (boss3SlaveLeftHandle_ != nil)
	{
		[boss3SlaveLeftHandle_ ActionBoss3SlaveDisappear];
	}
	if (boss3SlaveRightHandle_ != nil)
	{
		[boss3SlaveRightHandle_ ActionBoss3SlaveDisappear];
	}

	/*clear boom
	*/
	[g_LayerGameObject Boss2ClearBomb];
}

- (void)ActionBoss3SpecialActionEyeOpen
{
	if (state_ == ENEMY_STATE_DIE)
	{
		return;
	}

	[self StopAction];
	[self PlayAni:ENEMY_ANI_BOSS_3_EYE_OPEN];
}

- (void)ActionBoss3SpecialActionEyeClose
{
	if (state_ == ENEMY_STATE_DIE)
	{
		return;
	}

	[self StopAction];
	[self PlayAni:ENEMY_ANI_BOSS_3_EYE_CLOSE];
}

- (void)ActionBoss3SpecialQteSuccess
{
	if (state_ == ENEMY_STATE_DIE)
	{
		return;
	}

	[self ActionBoss3SpecialActionEyeClose];

	/*show life bar
	*/
	[lifeBar_ runAction:[CCShow action]];
}

- (void)ActionBoss3SpecialQteFailed
{
	if (state_ == ENEMY_STATE_DIE)
	{
		return;
	}

	NSString *_Path;

	_Path = [NSString stringWithUTF8String:g_CfgGameBoss3Data.ani_eye_open.path_table.back().c_str()];
	[image_ setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:_Path]];
	[self ActionBoss3SpecialAttackCharge];

	/*show life bar
	*/
	[lifeBar_ runAction:[CCShow action]];
}

- (void)ActionBoss3SpecialAttackCharge
{
	if (state_ == ENEMY_STATE_DIE)
	{
		return;
	}

	boss3ChargeParticle_ = [CCParticleSystemQuad particleWithFile:@"boss_003_charge.plist"];
	[self addChild:boss3ChargeParticle_];
	[self runAction:tcCreateActionCallBack(self, 4, @selector(CallBackBoss3ActionChargeOver:))];
}

- (void)ActionBoss3StageChange
{
	CCSequence *_Seq;
	id _ActionMoveOut, _ActionStand, _ActionMoveIn;
	CCCallFuncN *_CallBackStageChangeOver;

	if (state_ == ENEMY_STATE_DIE)
	{
		return;
	}

	state_ = ENEMY_STATE_BOSS3_STAGE_CHANGE;
	switch (flagBoss3Stage_)
	{
	case BOSS_3_STAGE_1: flagBoss3Stage_ = BOSS_3_STAGE_2; break;
	case BOSS_3_STAGE_2: flagBoss3Stage_ = BOSS_3_STAGE_3; break;
	case BOSS_3_STAGE_3: assert(false); break;
	default:;
	}
	[self StopAction];
	[self PlayAni:ENEMY_ANI_MOVE];
	_ActionMoveOut = tcCreateActionMove(self.positionInPixels, g_CfgGameScrrenArea[14].center, [self GetMoveSpeed]);
	_ActionStand = [action_move_in_pixel actionWithDuration:1.0f position:g_CfgGameScrrenArea[14].center];
	_ActionMoveIn = tcCreateActionMove(g_CfgGameScrrenArea[14].center, g_CfgGameScrrenArea[4].center, [self GetMoveSpeed]);
	_CallBackStageChangeOver = [CCCallFuncN actionWithTarget:self selector:@selector(CallBackBoss3ActionStageChangeOver:)];
	_Seq = [CCSequence actions:_ActionMoveOut, _ActionStand, _ActionMoveIn, _CallBackStageChangeOver, nil];
	[self runAction:_Seq];
}

- (void)ActionBoss3SlaveDead:(sprite_game_enemy *)Slave
{
	if (state_ == ENEMY_STATE_DIE)
	{
		return;
	}

	if (boss3SlaveLeftHandle_ == Slave)
	{
		boss3SlaveLeftHandle_ = nil;
		[self ActionBoss3CreateLeftSlave];
	}
	else if (boss3SlaveRightHandle_ == Slave)
	{
		boss3SlaveRightHandle_ = nil;
		[self ActionBoss3CreateRightSlave];
	}
}

- (void)ActionBoss3CreateLeftSlave
{
	if (state_ == ENEMY_STATE_DIE)
	{
		return;
	}

	[self schedule:@selector(tickBoss3CreateLeftSlave:) interval:5];
}

- (void)ActionBoss3CreateRightSlave
{
	if (state_ == ENEMY_STATE_DIE)
	{
		return;
	}

	[self schedule:@selector(tickBoss3CreateRightSlave:) interval:5];
}

- (void)CallBackBoss3ActionAppearMoveOver:(id)Sender
{
	[self PlayAni:ENEMY_ANI_BOSS_3_APPEAR];
}

- (void)CallBackBoss3ActionAppearAniOver:(id)Sender
{
	NSString *_Path;

	_Path = [NSString stringWithUTF8String:g_CfgGameBoss3Data.ani_move.path_table[0].c_str()];
	[image_ setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:_Path]];
	[self AiActionStandOver];
}

- (void)CallBackBoss3ActionSpecialAttackMoveOver:(id)Sender
{
	int i;

	/*special attack start
	*/
	g_LayerGameObject.flagFunctionLock = true;
	g_LayerGameObject.flagTouchLockArrow = true;
	g_LayerGameObject.flagTouchLockItem = true;
	[g_LayerGameObject Boss3SetZOrderOte:self];
	[g_LayerGameObject Boss3ClearArrow];

	/*pause time
	*/
	[g_SpriteGameTimeBar Pause];

	mask_.flagFadeOut = false;
	mask_.opacity = 255;

	for (i = 0; i < BOSS_3_QTE_EYE_COUNT; i++)
	{
		eye_[i].flagEyeClose = false;
	}

	[self ActionBoss3SpecialActionEyeOpen];
}

- (void)CallBackBoss3ActionEyeOpenAniOver:(id)Sender
{
	int i, j;
	int _Index;
	std::vector<CGPoint> _PointTable;
	std::vector<CGPoint>::iterator _PointTableIter;
	CGPoint _Point;
	NSString *_Path;

	_Path = [NSString stringWithUTF8String:g_CfgGameBoss3Data.ani_eye_open.path_table.back().c_str()];
	[image_ setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:_Path]];

	/*mask
	*/
	[mask_ runAction:[CCShow action]];
	[mask_ actionReady];
	mask_.positionInPixels = ccpSub(CGPointZero, self.positionInPixels);
	mask_.r = mask_.g = mask_.b = 0;

	/*eye
	*/
	_PointTable = g_CfgGameBoss3Data.child_eye_position_table;
	for (i = 0; i < BOSS_3_QTE_EYE_COUNT; i++)
	{
		_Index = rand() % _PointTable.size();
		_Point = _PointTable[_Index];
		_PointTableIter = _PointTable.begin();
		for (j = 0; j < _Index; j++, _PointTableIter++)
		{}
		_PointTable.erase(_PointTableIter);
		eye_[i].positionInPixels = ccpSub(_Point, self.positionInPixels);
	}

	/*open eye
	*/
	flagBoss3SpecialAttackEyeOpenIndex_ = 0;
	[eye_[flagBoss3SpecialAttackEyeOpenIndex_] runAction:[CCShow action]];
	[eye_[flagBoss3SpecialAttackEyeOpenIndex_] ActionEyeOpen];

	/*hide life bar
	*/
	[lifeBar_ runAction:[CCHide action]];
}

- (void)CallBackBoss3ActionEyeCloseAniOver:(id)Sender
{
	/*start special attack tick
	*/
	[self schedule:@selector(tickBoss3SpecialAttack:) interval:SPRITE_GAME_ENEMY_BOSS_3_SPECIAL_ATTACK_TIME];

	/*unlock touch
	*/
	g_LayerGameObject.flagFunctionLock = false;
	g_LayerGameObject.flagTouchLockArrow = false;
	g_LayerGameObject.flagTouchLockItem = false;
	[g_LayerGameObject ReadyArrow];

	/*default image
	*/
	[image_ setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithUTF8String:g_CfgGameBoss3Data.ani_eye_close.path_table.back().c_str()]]];

	/*create left and right slave
	*/
	[self Boss3CreateSlave];

	/*ai continue
	*/
	[self ActionStand:2.0f];
}

- (void)CallBackBoss3ActionChargeOver:(id)Sender
{
	sprite_game_bomb *_Laser;

	/*clear particle
	*/
	[self removeChild:boss3ChargeParticle_ cleanup:TRUE];
	boss3ChargeParticle_ = nil;

	/*bomb laser
	*/
	_Laser = [[sprite_game_bomb alloc] initSpriteGameBomb:BOMB_TYPE_6];
	[g_LayerGameObject AddBomb:_Laser];
	_Laser.positionInPixels = ccp(self.positionInPixels.x, self.positionInPixels.y - 80);
	[_Laser ActionAttack:2 And:[g_SpriteGameBridge GetBridgePositionByX:self.positionInPixels.x]];

	/*stup laser over callback
	*/
	[self runAction:tcCreateActionCallBack(self, 2, @selector(CallBackBoss3ActionLaserAttackOver:))];

	/*dec bridge point
	*/
	[g_SpriteGameBridge DecPoint:50];
}

- (void)CallBackBoss3ActionLaserAttackOver:(id)Sender
{
	[self ActionBoss3SpecialActionEyeClose];
}

- (void)CallBackBoss3ActionStageChangeOver:(id)Sender
{
	switch (flagBoss3Stage_)
	{
	case BOSS_3_STAGE_1: assert(false); break;
	case BOSS_3_STAGE_2:
		[self Boss3CreateSlave];
		[self AiActionMoveOver];
		break;
	case BOSS_3_STAGE_3:[self ActionBoss3SpecialAttack]; break;
	default:;
	}

	/*music
	*/
	switch (flagBoss3Stage_)
	{
	case BOSS_3_STAGE_2: MusicPlayGameBossStage2(); break;
	case BOSS_3_STAGE_3: MusicPlayGameBossStage3(); break;
	}
}

- (void)CallBackBoss3SpecialAttackChildEyeOpenOver:(sprite_game_enemy_eye *)Eye
{
	if (flagBoss3SpecialAttackEyeOpenIndex_ < BOSS_3_QTE_EYE_COUNT - 1)
	{
		flagBoss3SpecialAttackEyeOpenIndex_++;
		[eye_[flagBoss3SpecialAttackEyeOpenIndex_] runAction:[CCShow action]];
		[eye_[flagBoss3SpecialAttackEyeOpenIndex_] ActionEyeOpen];
	}
	else
	{
		flagBoss3SpecialAttackEyeOpenIndex_ = BOSS_3_QTE_EYE_COUNT - 1;
		touchState_ = ENEMY_TOUCH_TYPE_BOSS_3_QTE;
	}
}

- (void)CallBackBoss3SpecialAttackChildEyeCloseOver:(sprite_game_enemy_eye *)Eye
{
	int i;

	Eye.flagEyeClose = true;
	for (i = 0; i < BOSS_3_QTE_EYE_COUNT; i++)
	{
		if (!eye_[i].flagEyeClose)
		{
			return;
		}
	}
	if (!mask_.flagFadeOut)
	{
		mask_.flagFadeOut = true;
		[mask_ ActionFadeOut];
	}
}

- (void)CallBackBoss3SpecialAttackChildMaskFadeOutOver:(sprite_game_enemy_mask *)Mask
{
	[g_SpriteGameTimeBar Resume];
	[g_LayerGameObject Boss3SetZOrderNormal:self];
	if (flagBoss3SpecialQte_)
	{
		[self ActionBoss3SpecialQteSuccess];
	}
	else
	{
		[self ActionBoss3SpecialQteFailed];
	}
}

@end